package hyl.core.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyRef3 extends ClassLoader {
	private static final Logger log = LoggerFactory.getLogger(MyRef3.class);

	// 从War文件生成class
	public Class<?> loadClassFromWar(String warpath, String className) throws ClassNotFoundException {
		Class<?> result = null;
		byte[] classData = null;
		try {
			classData = getByteArrayFromWarFile(className, warpath);
			String s = className.replace("WEB-INF.classes.", "");
			result = defineClass(s, classData, 0, classData.length);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}

	private byte[] getByteArrayFromWarFile(String className, String warpath) {
		ZipFile zipfile = null;
		try {
			zipfile = new ZipFile(warpath);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		className = className.replace('.', '/');
		// System.out.println(className);
		try {
			ZipEntry zipEntry = zipfile.getEntry(className + ".class");
			if (zipEntry != null) {
				log.error("压缩类 zipEntry:" + zipEntry.getName());
				try {
					InputStream inputStream = zipfile.getInputStream(zipEntry);
					int arrayLength = inputStream.available();
					byte[] bytes = new byte[arrayLength];
					int pos = 0;
					while (true) {
						int n = inputStream.read(bytes, pos, arrayLength - pos);
						if (n <= 0)
							break;
						pos += n;
					}
					inputStream.close();
					return bytes;
				} catch (IOException exp) {
					exp.printStackTrace();
				}
			} else {
				// System.out.println("not found");
				log.error("not found");
			}
		} catch (Exception ex) {
			// ex.printStackTrace();
			return null;
		}
		return null;
	}

	/**
	 * 这个方法需要实例化后才能使用 ,主要用于 反射远程 传过来的jar ,用于分布式计算
	 * 
	 * @param jarpath
	 * @param className
	 * @return
	 * @throws ClassNotFoundException
	 */
	public Class<?> loadClassFromJar(String jarpath, String className) throws ClassNotFoundException {
		Class<?> result = null;
		byte[] classData = null;
		try {
			classData = getByteArrayFromJarFile(jarpath, className);
			this.defineClass(className, classData, 0, classData.length);
			result = this.defineClass(className, classData, 0, classData.length);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;
	}

	/**
	 * 以二进制方式 读取包中的class
	 * 
	 * 后期可以做rpc
	 * 
	 * @param jarpath
	 * @param className
	 * @return
	 */
	public static byte[] getByteArrayFromJarFile(String jarpath, String className) {
		JarFile jarFile = null;
		try {
			jarFile = new JarFile(jarpath);
		} catch (Exception ex) {
		}
		className = className.replace('.', '/');
		try {
			ZipEntry zipEntry = jarFile.getEntry(className + ".class");
			if (zipEntry != null) {
				try {
					InputStream inputStream = jarFile.getInputStream(zipEntry);
					int arrayLength = inputStream.available();
					byte[] bytes = new byte[arrayLength];
					int pos = 0;
					while (true) {
						int n = inputStream.read(bytes, pos, arrayLength - pos);
						if (n <= 0)
							break;
						pos += n;
					}
					inputStream.close();
					return bytes;
				} catch (IOException exp) {
					exp.printStackTrace();
				}
			}
		} catch (Exception ex) {
			// ex.printStackTrace();
			// return null;
		}
		return null;

	}
}
